DSGE-VAR Modeling ================== (Also known in the literature as BVAR-DSGE; the modern factory is ``dsge_var_model``.) Description ------------ The DSGE-VAR (also known as BVAR-DSGE) is a methodology that combines a BVAR and a DSGE model following Del Negro and Schorfheide (2004) and Del Negro, Schorfheide, Smets and Wouters (2007). There are two possible interpretations: the DSGE is used as a *prior* for the BVAR, or the BVAR serves to *relax* the tight restrictions in the DSGE. In the end you have four sub-models in one object: * the VAR model, * the VAR approximation of the DSGE model, * the DSGE model, * the BVAR model -- the VAR with the (VAR approximation of the) DSGE as prior. The DSGE can be a model with a simple instrument rule (e.g. a Taylor rule) or an optimal policy under commitment or under discretion. It can be stationary or non-stationary. .. contents:: :local: :depth: 2 A quick-start example ---------------------- A simple New Keynesian DSGE model ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :: dsgemodel = { 'model: New Keynesian model' '@endogenous X "Output gap" R "interest rate" P "Inflation" G U' '@exogenous EG "Demand shock" EU "Monetary Policy shock"' '@parameters beta "discount factor" kappa "Phillips curve slope" sigu sigg rhou rhog psi' '@observables P R' '@model' ' P = beta*P{+1} + kappa*X;' ' X = X{+1} - (R - P{+1} - G);' ' R = psi*P + U;' ' U = rhou*U{-1} + sigu*EU;' ' G = rhog*G{-1} + sigg*EG;' }; Setting up the BVAR-DSGE model ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :: nlags = 4; constant = false; mdl = dsge_var_model(dsgemodel, ... lag_length = nlags, ... constant_term = constant); Fixed parameters ~~~~~~~~~~~~~~~~~ :: mdl = set(mdl, parameters = {'beta', 0.96}); Priors ~~~~~~~ :: priors = struct(); % priors on the DSGE parameters priors.kappa = {0.2, 0.5, 0.5, 'gamma'}; priors.psi = {1.5, 2, 0.5, 'gamma'}; priors.rhou = {0.75, 0.75, 0.1, 'beta'}; priors.rhog = {0.75, 0.75, 0.1, 'beta'}; priors.sigu = {0.01, 0.01, 4, 'sichisq'}; priors.sigg = {0.01, 0.01, 4, 'sichisq'}; % prior on the DSGE-prior weight priors.dsge_prior_weight = {3, 3, 1, 'gamma'}; plotOpts = struct(); plotOpts.prior_trunc = 2e-3; rdist.plot(priors, plotOpts) Collecting and transforming the data ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :: d = fetch_fred({'CPALTT01USQ661S','BOGZ1FL072052006Q'}); db = struct(); db.P = log(d(1).series / lag(d(1).series, 1)); db.R = d(2).series / 100; Maximizing the posterior ~~~~~~~~~~~~~~~~~~~~~~~~~ :: mdlest = estimate(mdl, ... estim_priors = priors, ... data = db, ... data_demean = true, ... estim_start_date = date2serial('1960Q2'), ... estim_end_date = date2serial('2022Q3')); IRFs of the BVAR-DSGE at the maximized posterior ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :: myirfs_bvar_dsge = irf(mdlest); IRFs of the DSGE model at the maximized posterior ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :: myirfs_dsge = irf(mdlest.dsge); IRF comparison ~~~~~~~~~~~~~~~ :: myirfs = ts.concatenator(myirfs_bvar_dsge, myirfs_dsge); quick_irfs(mdlest.dsge, myirfs, {'P','R'}); Choosing the VAR representation ------------------------------- A DSGE-VAR carries three reduced-form representations, and the analytics path (``irf``, variance and historical decompositions) draws from whichever you select with the ``which_var`` option: * ``'var_dsge'`` *(default)* -- the Bayesian DSGE-VAR combination: the data VAR shrunk toward the DSGE-implied restrictions with weight ``dsge_prior_weight``. This is the BVAR-DSGE proper, and it is what ``irf(mdlest)`` returns above. * ``'var'`` -- the pure data VAR (OLS), the ``dsge_prior_weight -> 0`` limit. Use it to see what the data say with no DSGE shrinkage. * ``'var_approx'`` -- the DSGE-implied VAR, the ``dsge_prior_weight -> inf`` limit. Use it to see the DSGE's own finite-order VAR approximation. Select a representation with ``set`` and run the analytics as usual:: myirfs_data_var = irf(set(mdlest, 'which_var', 'var')); myirfs_dsge_var = irf(set(mdlest, 'which_var', 'var_approx')); The two limits bracket the Bayesian combination: ``'var'`` ignores the DSGE prior, ``'var_approx'`` ignores the data, and the default ``'var_dsge'`` interpolates between them according to ``dsge_prior_weight``.